/*
 * FiguraHerencia.java
 * 
 * Copyright (C) 2008 David Castellanos Serrano
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package dpoo.figuras;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;

/**
 *
 * @author david
 */
public class FiguraHerencia extends JComponent implements Observer {

    //origen y destino de la herencia representada por el objeto
    private FiguraClase origen, destino;
    
    //datos necesarios para la representación del objeto
    private Rectangle rectangle;
    private double size = 16.0;
    
    /**
     * Constructor de la clase FiguraHerencia
     * @param origen
     * @param destino
     */
    public FiguraHerencia(FiguraClase origen, FiguraClase destino) {
        this.origen = origen;       //o clase que implementa/hijo
        this.destino = destino;     //o interfaz a implementar/padre
        this.actualizarDatos();
    }


    
    //MANIPULACIÓN DE LOS DATOS DE LA CLASE
    /**
     * Devuelve la FiguraClase destino de la relación de herencia
     * @return
     */
    public FiguraClase getDestino() {
        return this.destino;
    }

    /**
     * Fija una nueva FiguraClase como destino de la relación de herencia
     * @param destino
     */
    public void setDestino(FiguraClase destino) {
        this.destino = destino;
        this.actualizarDatos();
        this.repaint();
    }
    
    
    
    /**
     * Actualiza los datos necesarios para la representación de la FiguraHerencia
     */
    private void actualizarDatos() {
        //obtengo el punto central de los objetos FiguraClase
        int x1 = this.origen.getX() + this.origen.getWidth() / 2;
        int y1 = this.origen.getY() + this.origen.getHeight() / 2;
        int x2 = this.destino.getX() + this.destino.getWidth() / 2;
        int y2 = this.destino.getY() + this.destino.getHeight() / 2;
        
        //calculo el extremo superior izquierdo del rectángulo
        int fooX, fooY;
        if(x1 < x2) {
            fooX = x1;
        } else {
            fooX = x2;
        }
        
        if(y1 < y2) {
            fooY = y1;
        } else {
            fooY = y2;
        }
        
        //calculo la altura y la anchura del rectángulo que forman las FiguraClase
        int width = Math.abs(x1 - x2) + 1;
        int height = Math.abs(y1 - y2) + 1;
        
        //actualizo el rectángulo
        this.rectangle = new Rectangle(fooX, fooY, width, height);
        this.setBounds(this.rectangle);
    }
    
    
    /**
     * Invoked by Swing to draw components.
     * @param g
     */
    @Override
    public void paint(Graphics g) {
        
        this.actualizarDatos();
        
        Graphics2D g2 = (Graphics2D) g;

        //obtengo el punto central de los objetos FiguraClase
        int x1 = this.origen.getX() + this.origen.getWidth() / 2;
        int y1 = this.origen.getY() + this.origen.getHeight() / 2;
        int x2 = this.destino.getX() + this.destino.getWidth() / 2;
        int y2 = this.destino.getY() + this.destino.getHeight() / 2;
        
        if(x1 < x2) {
            x1 = 0;
            x2 = Math.abs(this.origen.getX() - this.destino.getX());
        } else {
            x1 = Math.abs(this.origen.getX() - this.destino.getX());
            x2 = 0;
        }
        
        if(y1 < y2) {
            y1 = 0;
            y2 = Math.abs(this.origen.getY() - this.destino.getY());
        } else {
            y1 = Math.abs(this.origen.getY() - this.destino.getY());
            y2 = 0;
        }
        
        //FIXME
        GeneralPath polygon;
        int xf = x2;
        int yf = y2;
        x2 += (x1 - x2) / 2;
        y2 += (y1 - y2) / 2;
        double dx = x2 - x1;
        double dy = y2 - y1;
        double ra = java.lang.Math.sqrt(dx*dx + dy*dy);
        dx /= ra;
        dy /= ra;
        int x3 = (int)Math.round(x2-dx*size);
        int y3 = (int)Math.round(y2-dy*size);
        double r = 0.3*size;
        int x4 = (int)Math.round(x3+dy*r);
        int y4 = (int)Math.round(y3-dx*r);
        int x5 = (int)Math.round(x3-dy*r);
        int y5 = (int)Math.round(y3+dx*r);
        polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD,3);
        polygon.moveTo(x1, y1); polygon.lineTo(x3,y3);
        polygon.moveTo(x4,y4); polygon.lineTo(x2,y2);
        polygon.lineTo(x5,y5);polygon.lineTo(x4,y4);
        polygon.moveTo(x2,y2); polygon.lineTo(xf,yf);
        
        g2.draw(polygon);
    }

    
    //PATRÓN OBSERVER
    /**
     * Actualiza el estado de la FiguraHerencia respecto a las FiguraClase que relaciona
     */
    public void update() {
        this.repaint();
    }
}
